package com.joshua.spring.util;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.joshua.spring.constants.FormatterConstants.*;
import static com.joshua.spring.constants.SymbolConstants.EMPTY_STR;
import static com.joshua.spring.constants.SymbolConstants.POINT;

/**
 * projectName dragon-cloud
 * package com.joshua.spring.util
 * classname  TreeSeqUtils
 * <p>
 * description 树形结构生成
 * </p>
 *
 * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
 * @date 2020/9/14 10:50
 */
@Slf4j
public class TreeSeqUtils {
    private static final String FIRST = "1";
    private static final String STR_N = "n";
    /**
     * 正则  .num.
     */
    private static final String ROOT_SEQ_MATCHER = "\\.\\d+\\.";
    /**
     * 正则 ((.num)*n).  n是无数次的
     */
    private static final String SEQ_RULE_MATCHER = "((\\.\\d+)+)\\.";
    /**
     * 正则 ((.num)*n).  n是会被替换成具体的次数的
     */
    private static final String SEQ_MATCHER = "((\\.\\d+){n})\\.";
    private static final String SPLIT_REGEX = "\\.";
    /**
     * .%s.
     */
    private static final String ROOT_SEQ_FORMATTER = String.format(FORMATTER3S, POINT, FORMATTER1S, POINT);
    private static final String SEQ_FORMATTER = String.format(FORMATTER2S, FORMATTER2S, POINT);
    private static final String INDEX_FORMATTER = String.format(FORMATTER2S, FORMATTER1S, POINT);

    /**
     * description:
     *
     * @param entities
     * @return {@link String}
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/9/14 14:40
     */
    public static String rootSeqGen(List<TreeSeqEntity> entities) {
        if (CollectionUtils.isEmpty(entities)) {
            return String.format(ROOT_SEQ_FORMATTER, FIRST);
        }
        List<TreeSeqEntity> compareList = entities.stream().filter(e -> !StringUtils.isEmpty(e.getSeq()) && e.getSeq()
                .matches(ROOT_SEQ_MATCHER)).sorted(TreeSeqEntity::compareTo).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(compareList)) {
            return EMPTY_STR;
        }
        Integer order = lastSeqOrder(compareList.get(0).getSeq());
        return String.format(ROOT_SEQ_FORMATTER, order + 1);
    }

    /**
     * description:
     *
     * @param parentSeq
     * @param entities
     * @return {@link String}
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/9/14 14:40
     */
    public static String seqGen(String parentSeq, List<TreeSeqEntity> entities) {
        if (CollectionUtils.isEmpty(entities)) {
            return String.format(SEQ_FORMATTER, parentSeq, FIRST);
        }
        String[] parentSeqArray = parentSeq.split(SPLIT_REGEX);
        int level = parentSeqArray.length;
        if (level != 0) {
            List<TreeSeqEntity> compareList = entities.stream().filter(e -> !StringUtils.isEmpty(e.getSeq()) && e.getSeq()
                    .matches(SEQ_MATCHER.replace(STR_N, String.valueOf(level))))
                    .sorted(TreeSeqEntity::compareTo).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(compareList)) {
                return EMPTY_STR;
            }
            Integer order = lastSeqOrder(compareList.get(0).getSeq());
            return String.format(SEQ_FORMATTER, parentSeq, order + 1);
        }
        return EMPTY_STR;
    }

    public static Set<String> seqRollback(String seq) {
        Set<String> result = new HashSet<>();
        result.add(seq);
        if (seq.matches(SEQ_RULE_MATCHER)) {
            String[] seqArray = seq.split(SPLIT_REGEX);
            int length = seqArray.length;
            for (int i = length - 1; i > 1; i--) {
                seq = seq.substring(0, seq.lastIndexOf(String.format(INDEX_FORMATTER, seqArray[i])));
                result.add(seq);
            }
        }
        return result;
    }

    /**
     * projectName dragon-cloud
     * package com.joshua.spring.util.TreeSeqUtils
     * classname  TreeSeqEntity
     * <p>
     * description 树形序列模型
     * </p>
     *
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/9/14 10:50
     */
    @Data
    public static class TreeSeqEntity implements Comparable {
        private String id;
        private String name;
        private String parentId;
        private Integer treeLevel;
        private String seq;


        @Override
        public int compareTo(Object o) {
            Optional<Object> optional = Optional.ofNullable(o);
            if (optional.isPresent()) {
                TreeSeqEntity treeSeqEntity = (TreeSeqEntity) optional.get();
                String seq = treeSeqEntity.getSeq();
                Integer paramSeqOrder = lastSeqOrder(seq);
                Integer currentSeqOrder = lastSeqOrder(this.seq);
                return paramSeqOrder - currentSeqOrder;
            }
            return 0;
        }
    }

    /**
     * description: 获取序列中的最后一部分序列中的数字
     *
     * @param seq
     * @return {@link Integer}
     * @throws
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/9/14 11:32
     */
    private static Integer lastSeqOrder(String seq) {
        String noOfEndPoint = seq.substring(0, seq.lastIndexOf(POINT));
        int start = noOfEndPoint.lastIndexOf(POINT);
        String result = noOfEndPoint.substring(start + 1);
        return Integer.valueOf(result);
    }


    public static void main(String[] args) {
        Set<String> result = seqRollback(".1.2.3.4.");
        log.info(result.toString());
    }


}

